"use client";
import React, { useRef, useState } from "react";
import { usePinch } from "@use-gesture/react";
import { animated, useSpring } from "@react-spring/web";
import { clamp } from "@/utils";

interface IProps {
    min?: number;
    max?: number;
    children: React.ReactElement;
    onZoom?: (scale: number) => void;
}

export const Zoomable: React.FC<IProps> = ({
    min = 1,
    max = 3,
    children,
    onZoom,
}) => {
    const containerRef = useRef<HTMLDivElement>(null);
    const [scale, setScale] = useState(1);
    const initialScale = useRef(1); // 用于保存初始缩放值

    // 使用弹簧动画实现流畅缩放
    const [style, api] = useSpring(() => ({
        scale: 1,
        config: { mass: 1, tension: 300, friction: 40 },
    }));

    // 更新变换原点
    const updateTransformOrigin = (x: number, y: number) => {
        if (containerRef.current) {
            containerRef.current.style.transformOrigin = `${x}px ${y}px`;
        }
    };

    const bind = usePinch(
        ({ origin: [ox, oy], movement: [ms], event }) => {
            event.preventDefault();

            // 正确计算缩放值（基于初始值）
            const newScale = clamp(initialScale.current * ms, min, max);

            // 更新状态和动画
            setScale(newScale);
            api.start({ scale: newScale });
            onZoom?.(newScale);
            updateTransformOrigin(ox, oy);
        },
        {
            scaleBounds: { min, max }, // 正确设置边界
            rubberband: 0.2, // 启用弹性效果
            modifierKey: "ctrlKey", // PC端支持Ctrl+滚轮
            from: () => {
                initialScale.current = scale; // 记录初始缩放值
                return [scale, scale];
            },
            eventOptions: { passive: false },
        }
    );

    return (
        <animated.div
            className="w-full h-full"
            ref={containerRef}
            style={{
                ...style,
                touchAction: "none",
                willChange: "transform",
                ...children.props.style,
            }}
            {...bind()}
        >
            {children}
        </animated.div>
    );
};
